package ObjectOriented;

/**
 * 多态性
   override: 重写,子类重写父类的方法，方法名和参数列表相同，返回值类型也相同
      加上@Override可以让编译器帮助检查是否进行了正确的覆写。
      Java的实例方法调用是基于运行时的实际类型的动态调用，而非变量的声明类型。
   overload: 重载
   多态是指，针对某个类型的方法调用，其真正执行的方法取决于运行时期实际类型的方法。
 */

class Income {
  protected double income;
  public Income(double income) {
    this.income = income;
  }
  public double getTax() {
    return income * 0.1; // 税率10%
  }
  void test() {
    System.out.println("test");
  }
}
class Salary extends Income {
  public Salary(double income) {
    super(income);
  }
  @Override
  public double getTax() {
    if (income <= 5000) {
      return 0;
    }
    return (income - 5000) * 0.2;
  }
}

class StateCouncilSpecialAllowance extends Income {
  public StateCouncilSpecialAllowance(double income) {
    super(income);
  }
  @Override
  public double getTax() {
    return 0;
  }
}

public class Polymorphism {

  public double totalTax(Income... incomes) {
    double total = 0;
    for (Income income: incomes) {
      System.out.println(income.getTax());
      total = total + income.getTax();
    }
    return total;
  }
  public static void main(String[] args) {
    Income[] incomes = new Income[] {
      new Income(3000),
      new Salary(7500),
      new StateCouncilSpecialAllowance(15000)
    };
    System.out.println(new Polymorphism().totalTax(incomes));
  }
}